package org.dream.ui.chart.industry;

import java.awt.Color;
import java.awt.event.InputEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.swing.JFrame;

import org.dream.domain.Daydeal;
import org.dream.domain.Industry;
import org.dream.persistence.PersistenceService;
import org.dream.persistence.PersistenceServiceImpl;
import org.dream.service.StockService;
import org.dream.service.StockServiceImpl;
import org.dream.ui.MainFrame;
import org.dream.ui.chart.Chart;
import org.dream.ui.chart.Polyline;
import org.dream.ui.chart.XAxis;
import org.dream.ui.chart.YAxis;
import org.dream.ui.chart.impl.XAxisImpl;
import org.dream.ui.chart.impl.YAxisImpl;
import org.dream.util.ReflectUtil;

/**
 * 
 * @author qiuriyuchen E-mail:panpan_001@126.com
 */
public abstract class IndustryChartBuilder {
	private static final long serialVersionUID = 1L;
	private PersistenceService persistenceService = new PersistenceServiceImpl();
	protected StockService stockService = new StockServiceImpl();
	protected Map<String, List<Industry>> industryMap;
	protected Map<String, List<Industry>> industryAllMap;
	protected Map<String, Double> comMap;
	protected boolean calculate = false;
	protected double maxY = -100000;
	protected double minY = 100000;
	protected String stratDay;
	protected List<Industry> industryList;
	protected List<Daydeal> daydeals;

	protected abstract String getValuePropty();

	public void setCalculate(boolean calculate) {
		this.calculate = calculate;
	}

	/** 从文件中读取配置 */

	public IndustryChartBuilder() {
	}

	public Chart buildIndustryChart(Set<String> keys, boolean calculate) {
		this.calculate = calculate;

		getIndustryMap(keys);
		industryAllMap = industryMap;
		return buildchart();

	}

	public Chart reBuildIndustryChart(Set<String> keys) {

		industryMap = new LinkedHashMap<String, List<Industry>>();
		for (String key : keys) {
			industryMap.put(key, industryAllMap.get(key));
		}
		return buildchart();

	}

	public Chart cutIndustryChart(String startDay) {
		for (String key : industryMap.keySet()) {
			List<Industry> list = industryMap.get(key);
			int startIndex = 0;
			for (int i = 0; i < list.size(); i++) {
				Industry industry = list.get(i);
				if (startDay.compareTo(industry.getDay()) <= 0) {
					startIndex = i;
					break;

				}

			}
			industryMap.put(key, list.subList(startIndex, list.size()));
		}
		industryMap = stockService.CalIndustryMapValue(industryMap);
		return buildchart();

	}

	private Chart buildchart() {
		maxY = -100000;
		minY = 100000;
		industryList = industryMap.values().iterator().next();
		stratDay = industryList.get(0).getDay();
		daydeals = persistenceService.findDaydealsByCode("999999", stratDay, null);

		final Chart chart = getChart();
		chart.setBackground(Color.BLACK);

		// List<String> bkmcs = stockService.findIndustryBkmc(calculate);
		List<String> bkmcs = new ArrayList<String>();
		bkmcs.addAll(industryMap.keySet());
		for (int i = 0; i < bkmcs.size(); i++) {
			if (i == 0) {
				chart.addTuLi(bkmcs.get(i), Color.RED);
			} else if (i == 1) {
				chart.addTuLi(bkmcs.get(i), Color.YELLOW);
			} else if (i == 2) {
				chart.addTuLi(bkmcs.get(i), Color.BLUE);
			} else if (i == 3) {
				chart.addTuLi(bkmcs.get(i), Color.GREEN);
			} else if (i == 4) {
				chart.addTuLi(bkmcs.get(i), Color.CYAN);
			}
			if (bkmcs.size() < 10) {
				if (i == 5) {
					chart.addTuLi(bkmcs.get(i), Color.RED);
				} else if (i == 6) {
					chart.addTuLi(bkmcs.get(i), Color.YELLOW);
				} else if (i == 7) {
					chart.addTuLi(bkmcs.get(i), Color.BLUE);
				} else if (i == 8) {
					chart.addTuLi(bkmcs.get(i), Color.GREEN);
				} else if (i == 9) {
					chart.addTuLi(bkmcs.get(i), Color.CYAN);
				}
			}

			if (bkmcs.size() > 10) {
				if (i == bkmcs.size() - 5) {
					chart.addTuLi(bkmcs.get(i), Color.RED);
				} else if (i == bkmcs.size() - 4) {
					chart.addTuLi(bkmcs.get(i), Color.YELLOW);
				} else if (i == bkmcs.size() - 3) {
					chart.addTuLi(bkmcs.get(i), Color.BLUE);
				} else if (i == bkmcs.size() - 2) {
					chart.addTuLi(bkmcs.get(i), Color.GREEN);
				} else if (i == bkmcs.size() - 1) {
					chart.addTuLi(bkmcs.get(i), Color.CYAN);
				}
			}

		}
		for (String key : industryMap.keySet()) {
			List<Industry> industryList = industryMap.get(key);
			Color c = chart.getTuLi(key);
			// c = new Color(1, 1, 1, 0.3f);
			if (null != c) {
				new Polyline(industryList, chart, getValuePropty(), 1).setUi(c, 0);
			}

		}
		// 大盘线

		new Polyline(daydeals, chart, "CLOSE", 1).setUi(Color.RED, 3);
		// 鼠标双击，截图
		chart.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				super.mouseClicked(e);
				if (e.getClickCount() == 2) {
					int i = (int) chart.getXAxis().getXAxisModel().translatePxToValue(e.getX());
					MainFrame.getInstanse()
							.setCenterPanel(
									IndustryChartBuilder.this.cutIndustryChart((chart.getXAxis()).getXAxisModel()
											.getTickDay(i)));

				}

			}

		});
		chart.addKeyListener(new KeyAdapter() {
			@Override
			public void keyPressed(KeyEvent e) {
				super.keyPressed(e);
				if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
					industryMap = industryAllMap;
					MainFrame.getInstanse().setCenterPanel(IndustryChartBuilder.this.buildchart());
				}

			}
		});
		return chart;
	}

	public abstract void getIndustryMap(Set<String> keys);

	private Chart getChart() {

		/**
		 * 计算时间刻度，及股票价格高点和低点
		 */

		Map<Integer, String> tickViews = new HashMap<Integer, String>();// 从0开始
		int i = 1;
		for (Industry daydeal : industryList) {
			tickViews.put(i, daydeal.getDay());
			i++;
		}
		// 设定最小时间

		setMinMaxY();
		/** 构造坐标轴 */
		XAxis xAxis = (new XAxisImpl(1, industryList.size(), tickViews));
		YAxis yAxis = (new YAxisImpl(10, 1d));
		yAxis.getYAxisModel().setDrawGrid(true);
		final Chart chart = new Chart(xAxis, yAxis);

		chart.getXAxis().getXAxisModel().setDrawGrid(false);

		/** 添加鼠标点击监听器 */
		chart.addMouseListener(new MouseAdapter() {
			@Override
			public void mousePressed(MouseEvent e) {
				super.mousePressed(e);
				int mods = e.getModifiers();
				// 鼠标右键
				if ((mods & InputEvent.BUTTON3_MASK) != 0) {
					final int x = e.getX();
					final int y = e.getY();
					new IndustrySetDialog((JFrame) chart.getTopLevelAncestor(), true, x, y, IndustryChartBuilder.this);
				}

			}

		});
		return chart;
	}

	public void setMinMaxY() {
		for (String key : industryMap.keySet()) {
			List<Industry> industryList = industryMap.get(key);
			for (Industry industry : industryList) {
				Double value = (Double) ReflectUtil.getFieldValue(industry, getValuePropty());
				if (value.compareTo(maxY) > 0) {
					maxY = value;
				}
				if (value.compareTo(minY) < 0) {
					minY = value;
				}
			}
		}
		for (Daydeal daydeal : daydeals) {
			Double value = daydeal.getCLOSE();
			if (value.compareTo(maxY) > 0) {
				maxY = value;
			}
			if (value.compareTo(minY) < 0) {
				minY = value;
			}
		}
	}

}
